home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / atlbase.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  29.7 KB  |  1,092 lines

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10.  
  11. #ifndef __ATLBASE_H__
  12. #define __ATLBASE_H__
  13.  
  14. #ifndef __cplusplus
  15.   #error ATL requires C++ compilation (use a .cpp suffix)
  16. #endif
  17.  
  18. #ifdef _UNICODE
  19. #ifndef UNICODE
  20. #define UNICODE         // UNICODE is used by Windows headers
  21. #endif
  22. #endif
  23.  
  24. #ifdef UNICODE
  25. #ifndef _UNICODE
  26. #define _UNICODE        // _UNICODE is used by C-runtime/MFC headers
  27. #endif
  28. #endif
  29.  
  30. #ifdef _DEBUG
  31. #ifndef DEBUG
  32. #define DEBUG
  33. #endif
  34. #endif
  35.  
  36. // namespace and our templates don't quite work with earlier compiler
  37. // Can turn off namespace support directly, also
  38. #if _MSC_VER<1100
  39. #ifndef ATL_NO_NAMESPACE
  40. #define ATL_NO_NAMESPACE
  41. #endif
  42. #endif
  43.  
  44. ///////////////////////////////////////////////////////////////////////////////
  45. // __declspec(novtable) is used on a class declaration to prevent the vtable
  46. // pointer from being initialized in the constructor and destructor for the
  47. // class.  This has many benefits because the linker can now eliminate the
  48. // vtable and all the functions pointed to by the vtable.  Also, the actual
  49. // constructor and destructor code are now smaller.
  50. ///////////////////////////////////////////////////////////////////////////////
  51. // This should only be used on a class that is not directly createable but is
  52. // rather only used as a base class.  Additionally, the constructor and
  53. // destructor (if provided by the user) should not call anything that may cause
  54. // a virtual function call to occur back on the object.
  55. ///////////////////////////////////////////////////////////////////////////////
  56. // By default, the wizards will generate new ATL object classes with this
  57. // attribute (through the ATL_NO_VTABLE macro).  This is normally safe as long
  58. // the restriction mentioned above is followed.  It is always safe to remove
  59. // this macro from your class, so if in doubt, remove it.
  60. ///////////////////////////////////////////////////////////////////////////////
  61.  
  62. // Define MACRO to allow detection of Borland's Compiler
  63. //
  64. #if defined(__BORLANDC__)       // Detect Borland C++
  65. #define BCC32_COMPAT            // BCC32_COMPAT flags the Borland Compiler
  66. #define _ATL_NO_FORCE_LIBS      // Eliminate #pragma comment(lib, xxxx)
  67. #define _ATL_NO_DEBUG_CRT       // Avoid including <CRTDBG.H>
  68. #endif  //  __BORLANDC__
  69.  
  70. #if (_MSC_VER<1100) && !defined(BCC32_COMPAT)
  71. #define ATL_NO_VTABLE
  72. #else
  73. #ifdef _ATL_DISABLE_NO_VTABLE
  74. #define ATL_NO_VTABLE
  75. #else
  76. #define ATL_NO_VTABLE __declspec(novtable)
  77. #endif
  78. #endif
  79.  
  80. #ifndef _ATL_NO_PRAGMA_WARNINGS
  81. #pragma warning(disable: 4201) // nameless unions are part of C++
  82. #pragma warning(disable: 4127) // constant expression
  83. #pragma warning(disable: 4512) // can't generate assignment operator (so what?)
  84. #pragma warning(disable: 4514) // unreferenced inlines are common
  85. #pragma warning(disable: 4103) // pragma pack
  86. #pragma warning(disable: 4702) // unreachable code
  87. #pragma warning(disable: 4237) // bool
  88. #pragma warning(disable: 4710) // function couldn't be inlined
  89. #pragma warning(disable: 4355) // 'this' : used in base member initializer list
  90. #pragma warning(disable: 4097) // typedef name used as synonym for class-name
  91.  
  92. #if defined(BCC32_COMPAT)      // Additional warnings for Borland's Compiler
  93. #pragma warn -aus              // xxx is assigned a value that is never used
  94. #pragma warn -rch              // unreachable code (usually a break after a return)
  95. #endif // BCC32_COMPAT
  96.  
  97. #endif //!_ATL_NO_PRAGMA_WARNINGS
  98.  
  99. #include <windows.h>
  100. #include <winnls.h>
  101. #include <ole2.h>
  102.  
  103. #include <stddef.h>
  104. #include <tchar.h>
  105. #include <malloc.h>
  106. #ifndef _ATL_NO_DEBUG_CRT
  107. // Warning: if you define the above symbol, you will have
  108. // to provide your own definition of the _ASSERTE(x) macro
  109. // in order to compile ATL
  110.   #include <crtdbg.h>
  111. #endif
  112.  
  113. #include <olectl.h>
  114. #include <winreg.h>
  115. #include "atliface.h"
  116.  
  117. #ifndef _ATL_PACKING
  118. #define _ATL_PACKING 8
  119. #endif
  120. #pragma pack(push, _ATL_PACKING)
  121.  
  122. #include "atlconv.h"
  123.  
  124. #if defined(_ATL_DLL)
  125.   #pragma comment(lib, "atl.lib")
  126.   #define ATLAPI extern "C" HRESULT __stdcall
  127.   #define ATLAPI_(x) extern "C" x __stdcall
  128. #elif defined(_ATL_DLL_IMPL)
  129.   #define ATLAPI extern "C" HRESULT __declspec(dllexport) __stdcall
  130.   #define ATLAPI_(x) extern "C" x __declspec(dllexport) __stdcall
  131. #else
  132.   #define ATLAPI HRESULT __stdcall
  133.   #define ATLAPI_(x) x __stdcall
  134. #endif
  135.  
  136. #ifndef ATL_NO_NAMESPACE
  137. #ifndef _ATL_DLL_IMPL
  138. namespace ATL
  139. {
  140. #endif
  141. #endif
  142.  
  143. typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
  144. typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD dw);
  145. typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD dw);
  146. typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();
  147.  
  148. struct _ATL_OBJMAP_ENTRY
  149. {
  150.   const CLSID* pclsid;
  151.   HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  152.   _ATL_CREATORFUNC* pfnGetClassObject;
  153.   _ATL_CREATORFUNC* pfnCreateInstance;
  154.   IUnknown* pCF;
  155.   DWORD dwRegister;
  156.   _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  157.   HRESULT WINAPI RevokeClassObject()
  158.   {
  159.     return CoRevokeClassObject(dwRegister);
  160.   }
  161.   HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags)
  162.   {
  163.     IUnknown* p = NULL;
  164.     HRESULT hRes = pfnGetClassObject(pfnCreateInstance, IID_IUnknown, (LPVOID*) &p);
  165.     if (SUCCEEDED(hRes))
  166.       hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
  167.     if (p != NULL)
  168.       p->Release();
  169.     return hRes;
  170.   }
  171. };
  172.  
  173. struct _ATL_REGMAP_ENTRY
  174. {
  175.   LPCOLESTR     szKey;
  176.   LPCOLESTR     szData;
  177. };
  178.  
  179. struct _ATL_MODULE
  180. {
  181. // Attributes
  182. public:
  183.   UINT cbSize;
  184.   HINSTANCE m_hInst;
  185.   HINSTANCE m_hInstResource;
  186.   HINSTANCE m_hInstTypeLib;
  187.   _ATL_OBJMAP_ENTRY* m_pObjMap;
  188.   LONG m_nLockCnt;
  189.   HANDLE m_hHeap;
  190.   CRITICAL_SECTION m_csTypeInfoHolder;
  191.   CRITICAL_SECTION m_csWindowCreate;
  192.   CRITICAL_SECTION m_csObjMap;
  193. };
  194.  
  195. //This define makes debugging asserts easier.
  196. #define _ATL_SIMPLEMAPENTRY ((_ATL_CREATORARGFUNC*)1)
  197.  
  198. struct _ATL_INTMAP_ENTRY
  199. {
  200.   const IID* piid;       // the interface id (IID)
  201.   DWORD dw;
  202.   _ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr
  203. };
  204.  
  205. /////////////////////////////////////////////////////////////////////////////
  206. // QI Support
  207.  
  208. ATLAPI AtlInternalQueryInterface(void* pThis,
  209.   const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);
  210.  
  211. /////////////////////////////////////////////////////////////////////////////
  212. // Smart Pointer helpers
  213.  
  214. ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  215. ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);
  216.  
  217. /////////////////////////////////////////////////////////////////////////////
  218. // Inproc Marshaling helpers
  219. ATLAPI AtlFreeMarshalStream(IStream* pStream);
  220. ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream);
  221. ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk);
  222.  
  223. ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent);
  224.  
  225. /////////////////////////////////////////////////////////////////////////////
  226. // Connection Point Helpers
  227.  
  228. ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);
  229. ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);
  230.  
  231. /////////////////////////////////////////////////////////////////////////////
  232. // IDispatch Error handling
  233.  
  234. ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,
  235.   DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,
  236.   HINSTANCE hInst);
  237.  
  238. /////////////////////////////////////////////////////////////////////////////
  239. // Module
  240.  
  241. ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h);
  242. ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags);
  243. ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM);
  244. ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv);
  245. ATLAPI AtlModuleTerm(_ATL_MODULE* pM);
  246. ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID = NULL);
  247. ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID = NULL);
  248. ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE*pM, LPCOLESTR lpszRes,
  249.   BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg = NULL);
  250. ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);
  251.  
  252. #ifndef ATL_NO_NAMESPACE
  253. #ifndef _ATL_DLL_IMPL
  254. }; //namespace ATL
  255. #endif
  256. #endif
  257.  
  258. #ifndef ATL_NO_NAMESPACE
  259. namespace ATL
  260. {
  261. #endif
  262.  
  263. #if defined (_CPPUNWIND) & (defined(_ATL_EXCEPTIONS) | defined(_AFX))
  264. #define ATLTRY(x) try{x;} catch(...) {}
  265. #else
  266. #define ATLTRY(x) x;
  267. #endif
  268.  
  269. #ifdef _DEBUG
  270. void _cdecl AtlTrace(LPCTSTR lpszFormat, ...);
  271. #ifndef ATLTRACE
  272. #define ATLTRACE            AtlTrace
  273. #endif
  274. #define ATLTRACENOTIMPL(funcname)   ATLTRACE(_T("%s not implemented.\n"), funcname); return E_NOTIMPL
  275. #else
  276. inline void _cdecl AtlTrace(LPCTSTR , ...){}
  277. #ifndef ATLTRACE
  278. #define ATLTRACE            1 ? (void)0 : AtlTrace
  279. #endif
  280. #define ATLTRACENOTIMPL(funcname)   return E_NOTIMPL
  281. #endif //_DEBUG
  282.  
  283. #define offsetofclass(base, derived) ((DWORD)(static_cast<base*>((derived*)8))-8)
  284.  
  285. /////////////////////////////////////////////////////////////////////////////
  286. // Master version numbers
  287.  
  288. #define _ATL     1      // Active Template Library
  289. #define _ATL_VER 0x0200 // Active Template Library version 2.00
  290.  
  291. /////////////////////////////////////////////////////////////////////////////
  292. // Win32 libraries
  293.  
  294. #ifndef _ATL_NO_FORCE_LIBS
  295.   #pragma comment(lib, "kernel32.lib")
  296.   #pragma comment(lib, "user32.lib")
  297.   #pragma comment(lib, "ole32.lib")
  298.   #pragma comment(lib, "oleaut32.lib")
  299.   #pragma comment(lib, "olepro32.lib")
  300.   #pragma comment(lib, "uuid.lib")
  301.   #pragma comment(lib, "advapi32.lib")
  302. #endif // _ATL_NO_FORCE_LIBS
  303.  
  304. template <class T>
  305. class CComPtr
  306. {
  307. public:
  308.   typedef T _PtrClass;
  309.   CComPtr() {p=NULL;}
  310.   CComPtr(T* lp)
  311.   {
  312.     if ((p = lp) != NULL)
  313.       p->AddRef();
  314.   }
  315.   CComPtr(const CComPtr<T>& lp)
  316.   {
  317.     if ((p = lp.p) != NULL)
  318.       p->AddRef();
  319.   }
  320.   ~CComPtr() {if (p) p->Release();}
  321.   void Release() {if (p) p->Release(); p=NULL;}
  322.   operator T*() {return (T*)p;}
  323.   T& operator*() {_ASSERTE(p!=NULL); return *p; }
  324.   //The assert on operator& usually indicates a bug.  If this is really
  325.   //what is needed, however, take the address of the p member explicitly.
  326.   T** operator&() { _ASSERTE(p==NULL); return &p; }
  327.   T* operator->() { _ASSERTE(p!=NULL); return p; }
  328.   T* operator=(T* lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp);}
  329.   T* operator=(const CComPtr<T>& lp)
  330.   {
  331.     return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  332.   }
  333. #if _MSC_VER>1020
  334.   bool operator!(){return (p == NULL);}
  335. #else
  336.   BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  337. #endif
  338.   T* p;
  339. };
  340.  
  341. //Note: CComQIPtr<IUnknown, &IID_IUnknown> is not meaningful
  342. //      Use CComPtr<IUnknown>
  343. template <class T, const IID* piid>
  344. class CComQIPtr
  345. {
  346. public:
  347.   typedef T _PtrClass;
  348.   CComQIPtr() {p=NULL;}
  349.   CComQIPtr(T* lp)
  350.   {
  351.     if ((p = lp) != NULL)
  352.       p->AddRef();
  353.   }
  354.   CComQIPtr(const CComQIPtr<T,piid>& lp)
  355.   {
  356.     if ((p = lp.p) != NULL)
  357.       p->AddRef();
  358.   }
  359.   // If you get an error that this member is already defined, you are probably
  360.   // using a CComQIPtr<IUnknown, &IID_IUnknown>.  This is not necessary.
  361.   // Use CComPtr<IUnknown>
  362.   CComQIPtr(IUnknown* lp)
  363.   {
  364.     p=NULL;
  365.     if (lp != NULL)
  366.       lp->QueryInterface(*piid, (void **)&p);
  367.   }
  368.   ~CComQIPtr() {if (p) p->Release();}
  369.   void Release() {if (p) p->Release(); p=NULL;}
  370.   operator T*() {return p;}
  371.   T& operator*() {_ASSERTE(p!=NULL); return *p; }
  372.   //The assert on operator& usually indicates a bug.  If this is really
  373.   //what is needed, however, take the address of the p member explicitly.
  374.   T** operator&() { _ASSERTE(p==NULL); return &p; }
  375.   T* operator->() {_ASSERTE(p!=NULL); return p; }
  376.   T* operator=(T* lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp);}
  377.   T* operator=(const CComQIPtr<T,piid>& lp)
  378.   {
  379.     return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  380.   }
  381.   T* operator=(IUnknown* lp)
  382.   {
  383.     return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, *piid);
  384.   }
  385. #if _MSC_VER>1020
  386.   bool operator!(){return (p == NULL);}
  387. #else
  388.   BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  389. #endif
  390.   T* p;
  391. };
  392.  
  393. /////////////////////////////////////////////////////////////////////////////
  394. // CComBSTR
  395. class CComBSTR
  396. {
  397. public:
  398.   BSTR m_str;
  399.   CComBSTR()
  400.   {
  401.     m_str = NULL;
  402.   }
  403.   /*explicit*/ CComBSTR(int nSize, LPCOLESTR sz = NULL)
  404.   {
  405.     m_str = ::SysAllocStringLen(sz, nSize);
  406.   }
  407.   /*explicit*/ CComBSTR(LPCOLESTR pSrc)
  408.   {
  409.     m_str = ::SysAllocString(pSrc);
  410.   }
  411.   /*explicit*/ CComBSTR(const CComBSTR& src)
  412.   {
  413.     m_str = src.Copy();
  414.   }
  415.   CComBSTR& operator=(const CComBSTR& src);
  416.   CComBSTR& operator=(LPCOLESTR pSrc);
  417.   ~CComBSTR()
  418.   {
  419.     ::SysFreeString(m_str);
  420.   }
  421.   unsigned int Length() const
  422.   {
  423.     return SysStringLen(m_str);
  424.   }
  425.   operator BSTR() const
  426.   {
  427.     return m_str;
  428.   }
  429.   BSTR* operator&()
  430.   {
  431.     return &m_str;
  432.   }
  433.   BSTR Copy() const
  434.   {
  435.     return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  436.   }
  437.   void Attach(BSTR src)
  438.   {
  439.     _ASSERTE(m_str == NULL);
  440.     m_str = src;
  441.   }
  442.   BSTR Detach()
  443.   {
  444.     BSTR s = m_str;
  445.     m_str = NULL;
  446.     return s;
  447.   }
  448.   void Empty()
  449.   {
  450.     ::SysFreeString(m_str);
  451.     m_str = NULL;
  452.   }
  453. #if _MSC_VER>1020
  454.   bool operator!()
  455.   {
  456.     return (m_str == NULL);
  457.   }
  458. #else
  459.   BOOL operator!()
  460.   {
  461.     return (m_str == NULL) ? TRUE : FALSE;
  462.   }
  463. #endif
  464.   void Append(const CComBSTR& bstrSrc)
  465.   {
  466.     Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));
  467.   }
  468.   void Append(LPCOLESTR lpsz)
  469.   {
  470.     Append(lpsz, ocslen(lpsz));
  471.   }
  472.   // a BSTR is just a LPCOLESTR so we need a special version to signify
  473.   // that we are appending a BSTR
  474.   void AppendBSTR(BSTR p)
  475.   {
  476.     Append(p, SysStringLen(p));
  477.   }
  478.   void Append(LPCOLESTR lpsz, int nLen);
  479.  
  480.   CComBSTR& operator+=(const CComBSTR& bstrSrc)
  481.   {
  482.     AppendBSTR(bstrSrc.m_str);
  483.     return *this;
  484.   }
  485. #ifndef OLE2ANSI
  486.   /*explicit*/ CComBSTR(LPCSTR pSrc);
  487.   /*explicit*/ CComBSTR(int nSize, LPCSTR sz = NULL);
  488.   CComBSTR& operator=(LPCSTR pSrc);
  489.   void Append(LPCSTR);
  490. #endif
  491.   HRESULT WriteToStream(IStream* pStream);
  492.   HRESULT ReadFromStream(IStream* pStream);
  493. };
  494.  
  495. /////////////////////////////////////////////////////////////////////////////
  496. // CComVariant
  497.  
  498. class CComVariant : public tagVARIANT
  499. {
  500. // Constructors
  501. public:
  502.   CComVariant()
  503.   {
  504.     ::VariantInit(this);
  505.   }
  506.   ~CComVariant()
  507.   {
  508.     Clear();
  509.   }
  510.  
  511.   CComVariant(const VARIANT& varSrc)
  512.   {
  513.     ::VariantInit(this);
  514.     InternalCopy(&varSrc);
  515.   }
  516.  
  517.   CComVariant(const CComVariant& varSrc)
  518.   {
  519.     ::VariantInit(this);
  520.     InternalCopy(&varSrc);
  521.   }
  522.  
  523.   CComVariant(BSTR bstrSrc)
  524.   {
  525.     ::VariantInit(this);
  526.     *this = bstrSrc;
  527.   }
  528.   CComVariant(LPCOLESTR lpszSrc)
  529.   {
  530.     ::VariantInit(this);
  531.     *this = lpszSrc;
  532.   }
  533.  
  534. #ifndef OLE2ANSI
  535.   CComVariant(LPCSTR lpszSrc)
  536.   {
  537.     ::VariantInit(this);
  538.     *this = lpszSrc;}
  539. #endif
  540.  
  541. #if _MSC_VER>1020
  542.   CComVariant(bool bSrc)
  543.   {
  544.     ::VariantInit(this);
  545.     vt = VT_BOOL;
  546. #pragma warning(disable: 4310) // cast truncates constant value
  547.     boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  548. #pragma warning(default: 4310) // cast truncates constant value
  549.   }
  550. #endif
  551.  
  552.   CComVariant(int nSrc)
  553.   {
  554.     ::VariantInit(this);
  555.     vt = VT_I4;
  556.     lVal = nSrc;
  557.   }
  558.   CComVariant(BYTE nSrc)
  559.   {
  560.     ::VariantInit(this);
  561.     vt = VT_UI1;
  562.     bVal = nSrc;
  563.   }
  564.   CComVariant(short nSrc)
  565.   {
  566.     ::VariantInit(this);
  567.     vt = VT_I2;
  568.     iVal = nSrc;
  569.   }
  570.   CComVariant(long nSrc, VARTYPE vtSrc = VT_I4)
  571.   {
  572.     _ASSERTE(vtSrc == VT_I4 || vtSrc == VT_ERROR);
  573.     ::VariantInit(this);
  574.     vt = vtSrc;
  575.     lVal = nSrc;
  576.   }
  577.   CComVariant(float fltSrc)
  578.   {
  579.     ::VariantInit(this);
  580.     vt = VT_R4;
  581.     fltVal = fltSrc;
  582.   }
  583.   CComVariant(double dblSrc)
  584.   {
  585.     ::VariantInit(this);
  586.     vt = VT_R8;
  587.     dblVal = dblSrc;
  588.   }
  589.   CComVariant(CY cySrc)
  590.   {
  591.     ::VariantInit(this);
  592.     vt = VT_CY;
  593. #if !defined(BCC32_COMPAT) || defined(_ANONYMOUS_STRUCT)    
  594.     cyVal.Hi = cySrc.Hi;
  595.     cyVal.Lo = cySrc.Lo;
  596. #else
  597.     cyVal.s.Hi = cySrc.s.Hi;
  598.     cyVal.s.Lo = cySrc.s.Lo;
  599. #endif
  600.   }
  601.   CComVariant(IDispatch* pSrc)
  602.   {
  603.     ::VariantInit(this);
  604.     vt = VT_DISPATCH;
  605.     pdispVal = pSrc;
  606.     // Need to AddRef as VariantClear will Release
  607.     if (pdispVal != NULL)
  608.       pdispVal->AddRef();
  609.   }
  610.   CComVariant(IUnknown* pSrc)
  611.   {
  612.     ::VariantInit(this);
  613.     vt = VT_UNKNOWN;
  614.     punkVal = pSrc;
  615.     // Need to AddRef as VariantClear will Release
  616.     if (punkVal != NULL)
  617.       punkVal->AddRef();
  618.   }
  619.  
  620. // Assignment Operators
  621. public:
  622.   CComVariant& operator=(const CComVariant& varSrc)
  623.   {
  624.     InternalCopy(&varSrc);
  625.     return *this;
  626.   }
  627.   CComVariant& operator=(const VARIANT& varSrc)
  628.   {
  629.     InternalCopy(&varSrc);
  630.     return *this;
  631.   }
  632.  
  633.   CComVariant& operator=(BSTR bstrSrc);
  634.   CComVariant& operator=(LPCOLESTR lpszSrc);
  635.  
  636. #ifndef OLE2ANSI
  637.   CComVariant& operator=(LPCSTR lpszSrc);
  638. #endif
  639.  
  640. #if _MSC_VER>1020
  641.   CComVariant& operator=(bool bSrc);
  642. #endif
  643.   CComVariant& operator=(int nSrc);
  644.   CComVariant& operator=(BYTE nSrc);
  645.   CComVariant& operator=(short nSrc);
  646.   CComVariant& operator=(long nSrc);
  647.   CComVariant& operator=(float fltSrc);
  648.   CComVariant& operator=(double dblSrc);
  649.   CComVariant& operator=(CY cySrc);
  650.  
  651.   CComVariant& operator=(IDispatch* pSrc);
  652.   CComVariant& operator=(IUnknown* pSrc);
  653.  
  654. // Comparison Operators
  655. public:
  656. #if _MSC_VER>1020
  657.   bool operator==(const VARIANT& varSrc);
  658.   bool operator!=(const VARIANT& varSrc) {return !operator==(varSrc);}
  659. #else
  660.   BOOL operator==(const VARIANT& varSrc);
  661.   BOOL operator!=(const VARIANT& varSrc) {return !operator==(varSrc);}
  662. #endif
  663.  
  664. // Operations
  665. public:
  666.   HRESULT Clear() { return ::VariantClear(this); }
  667.   HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }
  668.   HRESULT Attach(VARIANT* pSrc);
  669.   HRESULT Detach(VARIANT* pDest);
  670.   HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL);
  671.   HRESULT WriteToStream(IStream* pStream);
  672.   HRESULT ReadFromStream(IStream* pStream);
  673.  
  674. // Implementation
  675. public:
  676.   HRESULT InternalClear();
  677.   void InternalCopy(const VARIANT* pSrc);
  678. };
  679. /////////////////////////////////////////////////////////////////////////////
  680. // GUID comparison
  681.  
  682. inline BOOL InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
  683. {
  684.    return (
  685.     ((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&
  686.     ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
  687.     ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
  688.     ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
  689. }
  690.  
  691. inline BOOL InlineIsEqualUnknown(REFGUID rguid1)
  692. {
  693.    return (
  694.     ((PLONG) &rguid1)[0] == 0 &&
  695.     ((PLONG) &rguid1)[1] == 0 &&
  696. #ifdef _MAC
  697.     ((PLONG) &rguid1)[2] == 0xC0000000 &&
  698.     ((PLONG) &rguid1)[3] == 0x00000046);
  699. #else
  700.     ((PLONG) &rguid1)[2] == 0x000000C0 &&
  701.     ((PLONG) &rguid1)[3] == 0x46000000);
  702. #endif
  703. }
  704.  
  705. /////////////////////////////////////////////////////////////////////////////
  706. // Threading Model Support
  707.  
  708. class CComCriticalSection
  709. {
  710. public:
  711.   void Lock() {EnterCriticalSection(&m_sec);}
  712.   void Unlock() {LeaveCriticalSection(&m_sec);}
  713.   void Init() {InitializeCriticalSection(&m_sec);}
  714.   void Term() {DeleteCriticalSection(&m_sec);}
  715.   CRITICAL_SECTION m_sec;
  716. };
  717.  
  718. class CComAutoCriticalSection
  719. {
  720. public:
  721.   void Lock() {EnterCriticalSection(&m_sec);}
  722.   void Unlock() {LeaveCriticalSection(&m_sec);}
  723.   CComAutoCriticalSection() {InitializeCriticalSection(&m_sec);}
  724.   ~CComAutoCriticalSection() {DeleteCriticalSection(&m_sec);}
  725.   CRITICAL_SECTION m_sec;
  726. };
  727.  
  728. class CComFakeCriticalSection
  729. {
  730. public:
  731.   void Lock() {}
  732.   void Unlock() {}
  733.   void Init() {}
  734.   void Term() {}
  735. };
  736.  
  737. class CComMultiThreadModelNoCS
  738. {
  739. public:
  740.   static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  741.   static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  742.   typedef CComFakeCriticalSection AutoCriticalSection;
  743.   typedef CComFakeCriticalSection CriticalSection;
  744.   typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  745. };
  746.  
  747. class CComMultiThreadModel
  748. {
  749. public:
  750.   static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  751.   static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  752.   typedef CComAutoCriticalSection AutoCriticalSection;
  753.   typedef CComCriticalSection CriticalSection;
  754.   typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  755. };
  756.  
  757. class CComSingleThreadModel
  758. {
  759. public:
  760.   static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
  761.   static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
  762.   typedef CComFakeCriticalSection AutoCriticalSection;
  763.   typedef CComFakeCriticalSection CriticalSection;
  764.   typedef CComSingleThreadModel ThreadModelNoCS;
  765. };
  766.  
  767. #ifndef _ATL_SINGLE_THREADED
  768. #ifndef _ATL_APARTMENT_THREADED
  769. #ifndef _ATL_FREE_THREADED
  770. #define _ATL_FREE_THREADED
  771. #endif
  772. #endif
  773. #endif
  774.  
  775. #if defined(_ATL_SINGLE_THREADED)
  776.   typedef CComSingleThreadModel CComObjectThreadModel;
  777.   typedef CComSingleThreadModel CComGlobalsThreadModel;
  778. #elif defined(_ATL_APARTMENT_THREADED)
  779.   typedef CComSingleThreadModel CComObjectThreadModel;
  780.   typedef CComMultiThreadModel CComGlobalsThreadModel;
  781. #else
  782.   typedef CComMultiThreadModel CComObjectThreadModel;
  783.   typedef CComMultiThreadModel CComGlobalsThreadModel;
  784. #endif
  785.  
  786. /////////////////////////////////////////////////////////////////////////////
  787. // CComModule
  788.  
  789. #define THREADFLAGS_APARTMENT 0x1
  790. #define THREADFLAGS_BOTH 0x2
  791. #define AUTPRXFLAG 0x4
  792.  
  793. struct _AtlCreateWndData
  794. {
  795.   void* m_pThis;
  796.   DWORD m_dwThreadID;
  797.   _AtlCreateWndData* m_pNext;
  798. };
  799.  
  800. class CComModule : public _ATL_MODULE
  801. {
  802. // Operations
  803. public:
  804.   _AtlCreateWndData* m_pCreateWndList;
  805.  
  806.   void AddCreateWndData(_AtlCreateWndData* pData, void* pObject);
  807.   void* ExtractCreateWndData();
  808.  
  809.   void Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h)
  810.   {
  811.     cbSize = sizeof(_ATL_MODULE);
  812.     m_pCreateWndList = NULL;
  813.     AtlModuleInit(this, p, h);
  814.   }
  815.   void Term()
  816.   {
  817.     AtlModuleTerm(this);
  818.   }
  819.  
  820.   LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  821.   LONG Unlock() {return CComGlobalsThreadModel::Decrement(&m_nLockCnt);}
  822.   LONG GetLockCount() {return m_nLockCnt;}
  823.  
  824.   HINSTANCE GetModuleInstance() {return m_hInst;}
  825.   HINSTANCE GetResourceInstance() {return m_hInstResource;}
  826.   HINSTANCE GetTypeLibInstance() {return m_hInstTypeLib;}
  827.  
  828.   // Registry support (helpers)
  829.   HRESULT RegisterTypeLib()
  830.   {
  831.     return AtlModuleRegisterTypeLib(this, NULL);
  832.   }
  833.   HRESULT RegisterTypeLib(LPCTSTR lpszIndex)
  834.   {
  835.     USES_CONVERSION;
  836.     return AtlModuleRegisterTypeLib(this, T2COLE(lpszIndex));
  837.   }
  838.   HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
  839.   {
  840.     return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);
  841.   }
  842.  
  843.   HRESULT UnregisterServer(const CLSID* pCLSID = NULL)
  844.   {
  845.     return AtlModuleUnregisterServer(this, pCLSID);
  846.   }
  847.  
  848.   // Resource-based Registration
  849.   HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
  850.     struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  851.   {
  852.     USES_CONVERSION;
  853.     return AtlModuleUpdateRegistryFromResourceD(this, T2COLE(lpszRes), bRegister,
  854.       pMapEntries);
  855.   }
  856.   HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
  857.     struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  858.   {
  859.     return AtlModuleUpdateRegistryFromResourceD(this,
  860.       (LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);
  861.   }
  862.  
  863.   #ifdef _ATL_STATIC_REGISTRY
  864.   // Statically linking to Registry Ponent
  865.   HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  866.     struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  867.   HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  868.     struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  869.   #endif //_ATL_STATIC_REGISTRY
  870.  
  871.   // Standard Registration
  872.   HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  873.     LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);
  874.   HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  875.     LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags);
  876.   HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  877.     LPCTSTR lpszVerIndProgID);
  878.  
  879.   // Register/Revoke All Class Factories with the OS (EXE only)
  880.   HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags)
  881.   {
  882.     return AtlModuleRegisterClassObjects(this, dwClsContext, dwFlags);
  883.   }
  884.   HRESULT RevokeClassObjects()
  885.   {
  886.     return AtlModuleRevokeClassObjects(this);
  887.   }
  888.  
  889.   // Obtain a Class Factory (DLL only)
  890.   HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  891.   {
  892.     return AtlModuleGetClassObject(this, rclsid, riid, ppv);
  893.   }
  894.  
  895.   // Only used in CComAutoThreadModule
  896.   HRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/)
  897.   {
  898.     return S_OK;
  899.   }
  900. };
  901.  
  902. /////////////////////////////////////////////////////////////////////////////////////////////
  903. // Thread Pooling classes
  904.  
  905. class _AtlAptCreateObjData
  906. {
  907. public:
  908.   _ATL_CREATORFUNC* pfnCreateInstance;
  909.   const IID* piid;
  910.   HANDLE hEvent;
  911.   LPSTREAM pStream;
  912.   HRESULT hRes;
  913. };
  914.  
  915. class CComApartment
  916. {
  917. public:
  918.   static UINT ATL_CREATE_OBJECT;
  919.   static DWORD WINAPI _Apartment(void* pv)
  920.   {
  921.     return ((CComApartment*)pv)->Apartment();
  922.   }
  923.   DWORD Apartment()
  924.   {
  925.     CoInitialize(NULL);
  926.     MSG msg;
  927.     while(GetMessage(&msg, 0, 0, 0))
  928.     {
  929.       if (msg.message == ATL_CREATE_OBJECT)
  930.       {
  931.         _AtlAptCreateObjData* pdata = (_AtlAptCreateObjData*)msg.lParam;
  932.         IUnknown* pUnk = NULL;
  933.         pdata->hRes = pdata->pfnCreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
  934.         if (SUCCEEDED(pdata->hRes))
  935.           pdata->hRes = CoMarshalInterThreadInterfaceInStream(*pdata->piid, pUnk, &pdata->pStream);
  936.         if (SUCCEEDED(pdata->hRes))
  937.         {
  938.           pUnk->Release();
  939.           ATLTRACE(_T("Object created on thread = %d\n"), GetCurrentThreadId());
  940.         }
  941.         SetEvent(pdata->hEvent);
  942.       }
  943.       DispatchMessage(&msg);
  944.     }
  945.     CoUninitialize();
  946.     return 0;
  947.   }
  948.   LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  949.   LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  950.   }
  951.   LONG GetLockCount() {return m_nLockCnt;}
  952.  
  953.   DWORD m_dwThreadID;
  954.   HANDLE m_hThread;
  955.   LONG m_nLockCnt;
  956. };
  957.  
  958. class CComSimpleThreadAllocator
  959. {
  960. public:
  961.   CComSimpleThreadAllocator()
  962.   {
  963.     m_nThread = 0;
  964.   }
  965.   int GetThread(CComApartment* /*pApt*/, int nThreads)
  966.   {
  967.     if (++m_nThread == nThreads)
  968.       m_nThread = 0;
  969.     return m_nThread;
  970.   }
  971.   int m_nThread;
  972. };
  973.  
  974. #if _MSC_VER>1020
  975. template <class ThreadAllocator = CComSimpleThreadAllocator>
  976. #else
  977. template <class ThreadAllocator>
  978. #endif
  979. class CComAutoThreadModule : public CComModule
  980. {
  981. public:
  982.   void Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, int nThreads = GetDefaultThreads());
  983.   ~CComAutoThreadModule();
  984.   HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj);
  985.   LONG Lock();
  986.   LONG Unlock();
  987.   DWORD dwThreadID;
  988.   int m_nThreads;
  989.   CComApartment* m_pApartments;
  990.   ThreadAllocator m_Allocator;
  991.   static int GetDefaultThreads()
  992.   {
  993.     SYSTEM_INFO si;
  994.     GetSystemInfo(&si);
  995.     return si.dwNumberOfProcessors * 4;
  996.   }
  997. };
  998.  
  999.  
  1000.  
  1001.  
  1002. #ifdef _ATL_STATIC_REGISTRY
  1003. #define UpdateRegistryFromResource UpdateRegistryFromResourceS
  1004. #else
  1005. #define UpdateRegistryFromResource UpdateRegistryFromResourceD
  1006. #endif
  1007.  
  1008. /////////////////////////////////////////////////////////////////////////////
  1009. // CRegKey
  1010.  
  1011. class CRegKey
  1012. {
  1013. public:
  1014.   CRegKey();
  1015.   ~CRegKey();
  1016.  
  1017. // Attributes
  1018. public:
  1019.   operator HKEY() const;
  1020.   HKEY m_hKey;
  1021.  
  1022. // Operations
  1023. public:
  1024.   LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
  1025.   LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
  1026.   LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);
  1027.   LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  1028.  
  1029.   LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  1030.   static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,
  1031.     LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  1032.  
  1033.   LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  1034.     LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,
  1035.     REGSAM samDesired = KEY_ALL_ACCESS,
  1036.     LPSECURITY_ATTRIBUTES lpSecAttr = NULL,
  1037.     LPDWORD lpdwDisposition = NULL);
  1038.   LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,
  1039.     REGSAM samDesired = KEY_ALL_ACCESS);
  1040.   LONG Close();
  1041.   HKEY Detach();
  1042.   void Attach(HKEY hKey);
  1043.   LONG DeleteSubKey(LPCTSTR lpszSubKey);
  1044.   LONG RecurseDeleteKey(LPCTSTR lpszKey);
  1045.   LONG DeleteValue(LPCTSTR lpszValue);
  1046. };
  1047.  
  1048. inline CRegKey::CRegKey()
  1049. {m_hKey = NULL;}
  1050.  
  1051. inline CRegKey::~CRegKey()
  1052. {Close();}
  1053.  
  1054. inline CRegKey::operator HKEY() const
  1055. {return m_hKey;}
  1056.  
  1057. inline HKEY CRegKey::Detach()
  1058. {
  1059.   HKEY hKey = m_hKey;
  1060.   m_hKey = NULL;
  1061.   return hKey;
  1062. }
  1063.  
  1064. inline void CRegKey::Attach(HKEY hKey)
  1065. {
  1066.   _ASSERTE(m_hKey == NULL);
  1067.   m_hKey = hKey;
  1068. }
  1069.  
  1070. inline LONG CRegKey::DeleteSubKey(LPCTSTR lpszSubKey)
  1071. {
  1072.   _ASSERTE(m_hKey != NULL);
  1073.   return RegDeleteKey(m_hKey, lpszSubKey);
  1074. }
  1075.  
  1076. inline LONG CRegKey::DeleteValue(LPCTSTR lpszValue)
  1077. {
  1078.   _ASSERTE(m_hKey != NULL);
  1079.   return RegDeleteValue(m_hKey, (LPTSTR)lpszValue);
  1080. }
  1081.  
  1082. #pragma pack(pop)
  1083.  
  1084. #ifndef ATL_NO_NAMESPACE
  1085. }; //namespace ATL
  1086. using namespace ATL;
  1087. #endif
  1088.  
  1089. #endif // __ATLBASE_H__
  1090.  
  1091. /////////////////////////////////////////////////////////////////////////////
  1092.